
#include "stdafx.h"

#ifdef UNDER_CE

#include <windows.h>
#include <commctrl.h>

#include "miscutil.h"
#include "SmpTst.h"
#include "CmdLnPars.h"

extern "C" HANDLE LoadKernelLibrary(LPCWSTR lpszFileName);		//pkfuncs.h
extern "C" HANDLE ActivateService(LPCWSTR lpszDevKey, DWORD dwClientInfo);	//service.h


BOOL UnLoadDrv(const TCHAR* pcszDrvName, const TCHAR* pcszDrvPath)
{
	LONG ret;
	HKEY hkey, hkeyDrv;
	DWORD i;

	ret=RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Drivers\\Active"), 0, KEY_READ, &hkey); 
	if(ERROR_SUCCESS!=ret)
	{
		return FALSE;
	}

	DWORD dwType;
	TCHAR buf[MAX_PATH];
	DWORD dwCbData;
	HANDLE h;
	for(i=0; ; i++)
	{
		TCHAR keyName[MAX_PATH];
		DWORD dwLen=ARRAYOF(keyName);

		ret=RegEnumKeyEx(hkey, i, keyName, &dwLen, NULL, NULL, NULL, NULL);
		if(ERROR_SUCCESS!=ret)
		{
			break;
		}

		ret=RegOpenKeyEx(hkey, keyName, 0, KEY_READ, &hkeyDrv); 
		if(ERROR_SUCCESS!=ret)
		{
			continue;
		}
		
		dwCbData=ARRAYOF(buf);
		if( (pcszDrvName
				&& (ERROR_SUCCESS==RegQueryValueEx(hkeyDrv, _T("Name"), NULL, &dwType, (BYTE*)buf, &dwCbData))
				&& (REG_SZ==dwType)
				&& (0==_tcscmp(pcszDrvName, buf)) )
			||(pcszDrvPath
				&& (ERROR_SUCCESS==RegQueryValueEx(hkeyDrv, _T("Key"), NULL, &dwType, (BYTE*)buf, &dwCbData))
				&& (REG_SZ==dwType)
				&& (0==_tcscmp(pcszDrvPath, buf)) ) )
		{
			dwCbData=sizeof(h);
			if((ERROR_SUCCESS==RegQueryValueEx(hkeyDrv, _T("Hnd"), NULL, &dwType, (BYTE*)&h, &dwCbData))
				&& (REG_DWORD==dwType) )
			{
				if(DeactivateDevice(h))
				{
					return TRUE;
				}
				else
				{
					return FALSE;
				}
			}
		}
		
		RegCloseKey(hkeyDrv);
	}

	RegCloseKey(hkey);

	return FALSE;
}

_tstring gLD_strDrvReg;
_tstring gLD_strUDrvName;
_tstring gLD_strUDrvReg;
DWORD gLD_strUDrvHdl;
DWORD gLD_strUDrvType;
_tstring gLD_strSvcReg;
_tstring gLD_strKDName;


extern "C" void ld_drv(SmpTstFunCntx* pv)
{
	HANDLE h=ActivateDevice(gLD_strDrvReg.c_str(), 0);
	if(NULL==h)
	{
		SMPTST_RSLT_RETURN(pv, FALSE, (TEXT("load driver of registry:%s faild:%d!"), gLD_strDrvReg.c_str(), GetLastError()));
	}
	else
	{
		SMPTST_RSLT_RETURN(pv, TRUE, (TEXT("load driver of registry:%s successed!"), gLD_strDrvReg.c_str()));
	}
}

extern "C" void ld_unld(SmpTstFunCntx* pv)
{
	if(gLD_strUDrvType>2)
	{
		gLD_strUDrvType=2;
	}
	
	if(0==gLD_strUDrvType)
	{
		if( gLD_strUDrvName.empty()
			|| !UnLoadDrv(gLD_strUDrvName.c_str(), NULL) )
		{
			SMPTST_RSLT_RETURN(pv, FALSE, (TEXT("UnLoadDrv driver_name:%s faild:%d!"), gLD_strUDrvName.c_str(), GetLastError()));
		}
		else
		{
			SMPTST_RSLT_RETURN(pv, TRUE, (TEXT("UnLoadDrv driver_name:%s successed!"), gLD_strUDrvName.c_str()));
		}
	}
	else if(1==gLD_strUDrvType)
	{
		if( gLD_strUDrvReg.empty()
			|| !UnLoadDrv(NULL, gLD_strUDrvReg.c_str()) )
		{
			SMPTST_RSLT_RETURN(pv, FALSE, (TEXT("UnLoadDrv reg_path:%s faild:%d!"), gLD_strUDrvReg.c_str(), GetLastError()));
		}
		else
		{
			SMPTST_RSLT_RETURN(pv, TRUE, (TEXT("UnLoadDrv reg_path:%s successed!"), gLD_strUDrvReg.c_str()));
		}
	}
	else
	{
		if(DeactivateDevice((HANDLE)gLD_strUDrvHdl))
		{
			SMPTST_RSLT_RETURN(pv, FALSE, (TEXT("UnLoadDrv handle:0x%x faild:%d!"), gLD_strUDrvHdl, GetLastError()));
		}
		else
		{
			SMPTST_RSLT_RETURN(pv, TRUE, (TEXT("UnLoadDrv  handle:0x%x successed!"), gLD_strUDrvHdl));
		}
	}
}

extern "C" void ld_svc(SmpTstFunCntx* pv)
{
	if(NULL==ActivateService(gLD_strSvcReg.c_str(), 0))
	{
		SMPTST_RSLT_RETURN(pv, FALSE, (_T("load service reg:%s faild:%d!\r\n"), gLD_strSvcReg.c_str(), GetLastError()));
	}
	else
	{
		SMPTST_RSLT_RETURN(pv, TRUE, (_T("load service reg:%s successed!\r\n"), gLD_strSvcReg.c_str()));
	}
}

extern "C" void ld_kdll(SmpTstFunCntx* pv)
{
	if(NULL==LoadKernelLibrary(gLD_strKDName.c_str()))
	{
		SMPTST_RSLT_RETURN(pv, FALSE, (_T("load kernel dll:%s faild:%d!\r\n"), gLD_strKDName.c_str(), GetLastError()));
	}
	else
	{
		SMPTST_RSLT_RETURN(pv, TRUE, (_T("load kernel dll:%s successed!\r\n"), gLD_strKDName.c_str()));
	}
}


SMPTST_GROUP(LOAD_DLLS, TEXT("LOAD DLLS"));
	SMPTST_SUB_FUNCTION(ld_drv, TEXT("load_driver(ld_drv_reg)"), LOAD_DLLS);
	SMPTST_SUB_FUNCTION(ld_unld, TEXT("unload_driver(ld_udrv_name|ld_udrv_reg|ld_udrv_hdl)"), LOAD_DLLS);
	SMPTST_SUB_FUNCTION(ld_svc, TEXT("load_service(ld_svc_reg)"), LOAD_DLLS);
	SMPTST_SUB_FUNCTION(ld_kdll, TEXT("load_kernel_dll(ld_kdll_name)"), LOAD_DLLS);

CMDLINE_INIT_NAME_VAL(_T("_ld"), _tstring, gLD_strTstOptions, _T(""), TEXT("USE \"/tst_var:ld_\" TO LIST LOAD DLLS OPTIONS\r\n"), FALSE);
CMDLINE_INIT_EXT_NAME_VAL(_T("ld_drv_reg"), _tstring, gLD_strDrvReg, TEXT("driver regpath:DVR_REG_PATH <under HKEY_LOCAL_MACHINE>\r\n"), FALSE);
CMDLINE_INIT_EXT_NAME_VAL(_T("ld_udrv_name"), _tstring, gLD_strUDrvName, TEXT("unload driver name:DRV_DLL_NAME such as COM1:\r\n"), FALSE);
CMDLINE_INIT_EXT_NAME_VAL(_T("ld_udrv_reg"), _tstring, gLD_strUDrvReg, TEXT("unload driver regpath:DVR_REG_PATH <under HKEY_LOCAL_MACHINE>\r\n"), FALSE);
CMDLINE_INIT_EXT_NAME_VAL(_T("ld_udrv_hdl"), DWORD, gLD_strUDrvHdl, TEXT("unload driver handle:HANDLE\r\n"), FALSE);
CMDLINE_INIT_EXT_NAME_VAL(_T("ld_udrv_type"), DWORD, gLD_strUDrvType, TEXT("unload driver type, 0:name, 1:reg, 2, handle\r\n"), FALSE);
CMDLINE_INIT_EXT_NAME_VAL(_T("ld_svc_reg"), _tstring, gLD_strSvcReg, TEXT("service regpath:DVR_REG_PATH <under HKEY_LOCAL_MACHINE\\Services\\lpszDevKey>\r\n"), FALSE);
CMDLINE_INIT_EXT_NAME_VAL(_T("ld_kdll_name"), _tstring, gLD_strKDName, TEXT("load dll to kernel :KNL_DLL_NAME\r\n"), FALSE);

#endif	//#ifdef UNDER_CE
